import type { ComponentStyleIdType } from '../../types/interfaces'
import type { QuickSearchTag, SearchBoxProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ICON_IDS } from '../../lib/icons/types/constants'
import { ToolKit } from '../../lib/utils/toolkit'
import { ComponentStyleId, ComponentStyleMode } from '../../types/constants'
import { TextInput } from '../text_input'
import { styles } from './styles'
import { DEFAULT_SEARCH_BOX_PROPS } from './types'

export class SearchBox extends UIComponent<SearchBoxProps> {
  id: string = 'search-box'
  readonly description: string = '搜索框组件'
  readonly styleId: string = ComponentStyleId[this.name]
  private isQuickSearch: boolean = false
  readonly componentStyleType: ComponentStyleMode = ComponentStyleMode.Dynamic

  get name(): ComponentStyleIdType {
    return 'SearchBox'
  }

  get className(): string {
    return `${this.props.id}-custom-search-box`
  }

  constructor(props: SearchBoxProps) {
    super({
      ...DEFAULT_SEARCH_BOX_PROPS,
      ...props,
    })

    this.registerStyles()
  }

  ELEMENT_SELECTORS = {
    input: { selector: `#${this.props.id}`, dynamic: false, unique: true },
    clearBtn: { selector: '.clear-btn', dynamic: false, unique: false },
    quickTags: { selector: '.quick-search-tags', dynamic: false, unique: false },
  }

  /**
   * 设置搜索框的值
   * @param value 要设置的值
   * @param triggerEvent 是否触发change事件
   */
  setValue(value: string, triggerEvent: boolean = true): void {
    const $input = this.getElement('input')
    if ($input) {
      $input.val(value)
      this.toggleClearButton(!!value)
      if (triggerEvent) {
        $input.trigger('input')
      }
    }
  }

  /**
   * 获取搜索框当前值
   */
  getValue(): string {
    return this.getElement('input')?.val()?.toString() || ''
  }

  /**
   * 设置是否快捷搜索
   */
  enableQuickSearch(): void {
    this.isQuickSearch = true
  }

  /**
   * 清空搜索框
   */
  clear(): void {
    this.setValue('')
  }

  /**
   * 渲染组件
   */
  render(): string {
    const {
      showQuickSearch,
      quickSearchTags,
    } = this.props as SearchBoxProps

    return `
      <div class="${this.className} search-box">
        <div class="search-input-container">
          ${this.renderTextInput()}
          <span class="search-icon">🔍</span>
          <button class="clear-btn" disabled>
            ${this.iconService.api.icon.asSvg(ICON_IDS.action.close)}
          </button>
        </div>
        ${showQuickSearch && quickSearchTags ? this.renderQuickSearchTags(quickSearchTags) : ''}
      </div>
    `
  }

  /**
   * 渲染文本输入框
   */
  private renderTextInput(): string {
    const { id, placeholder } = this.props

    return new TextInput({
      id,
      type: 'text',
      placeholder,
      value: '',
    }).render()
  }

  /**
   * 渲染快捷搜索标签
   * @param tags 标签配置
   */
  renderQuickSearchTags(tags: QuickSearchTag[]): string {
    return `
      <div class="quick-search-tags">
        ${tags.map(tag => `
          <span class="tag" data-type="${tag.type}">
            ${tag.label}
            ${tag.count ? `<span class="tag-count">(${tag.count})</span>` : ''}
          </span>
        `).join('')}
      </div>
    `
  }

  /**
   * 更新快捷搜索标签计数
   * @param tags 新的标签配置
   */
  updateQuickSearchTagsCount(tags: QuickSearchTag[]): void {
    this.getElement('quickTags')?.find('.tag')?.each((_, tag) => {
      const type = $(tag).data('type')
      const matchedTags = tags.find(tag => tag.type === type)
      const count = matchedTags?.count || 0
      const label = matchedTags?.label

      $(tag).text(`${label}（${count}）`)
    })
  }

  /**
   * 绑定事件监听
   */
  bindEvents(): void {
    this.bindInputEvent()
    this.bindClearEvent()
    this.bindQuickTagEvent()
  }

  /**
   * 绑定输入框事件
   */
  private bindInputEvent(): void {
    const { onSearch, debounceTime } = this.props as SearchBoxProps
    const $input = this.getElement('input')

    if ($input && onSearch) {
      $input.on('input', ToolKit.func.debounce((e: JQuery.ChangeEvent) => {
        const value = $(e.currentTarget).val()?.toString() || ''
        this.toggleClearButton(!!value)
        onSearch(value, this.isQuickSearch)
        if (this.isQuickSearch) {
          this.isQuickSearch = false
        }
      }, debounceTime || 300))
    }
  }

  /**
   * 绑定清除按钮事件
   */
  private bindClearEvent(): void {
    const $clearBtn = this.getElement('clearBtn')
    const $input = this.getElement('input')

    if ($clearBtn && $input) {
      $clearBtn.on('click', (e) => {
        e.preventDefault()
        this.clear()
        $input.trigger('focus')
      })
    }
  }

  /**
   * 绑定快捷标签事件
   */
  private bindQuickTagEvent(): void {
    const { onQuickTagClick } = this.props as SearchBoxProps
    const $tags = this.getElement('quickTags')?.find('.tag')

    if ($tags && onQuickTagClick) {
      $tags.on('click', (e) => {
        const type = $(e.currentTarget).data('type')
        onQuickTagClick(type)
      })
    }
  }

  /**
   * 切换清除按钮状态
   * @param show 是否显示
   */
  private toggleClearButton(show: boolean): void {
    this.getElement('clearBtn')?.prop('disabled', !show)
  }

  /**
   * 获取组件样式
   */
  getStyles(): string {
    return styles(this.className, this.props.quickSearchTags)
  }

  /**
   * 重置组件
   */
  reset(): void {
    this.clear()
  }

  /**
   * 销毁组件
   */
  destroy(): void {
    super.destroy()
  }
}
